﻿using System;
using System.Collections.Generic;
using System.Text;

using System.Diagnostics;
using System.Runtime.InteropServices;

namespace CommonLibrary
{
    public abstract class MemoryHelper
    {
        [DllImportAttribute("kernel32.dll", EntryPoint = "OpenProcess")]
        public static extern IntPtr OpenProcess
        (
            int dwDesiredAccess,
            bool bInheritHandle,
            int dwProcessId
        );

        [DllImport("kernel32.dll")]
        private static extern void CloseHandle
        (
            IntPtr hObject
        );


        //获取窗体的进程标识ID
        public static int GetPid(string windowTitle)
        {
            Process[] arrayProcess = Process.GetProcesses();
            foreach (Process p in arrayProcess)
            {
                if (p.MainWindowTitle.IndexOf(windowTitle) != -1)
                {
                    return p.Id;
                }
            }

            return 0;
        }

        public static List<int> GetPidListByTitle(string windowTitle)
        {
            List<int> listProcess = new List<int>();

            Process[] arrayProcess = Process.GetProcesses();

            foreach (Process p in arrayProcess)
            {
                if (p.MainWindowTitle.IndexOf(windowTitle) != -1)
                {
                    listProcess.Add(p.Id);
                }
            }

            return listProcess;
        }


        //根据进程名获取PID
        public static int GetPidByProcessName(string processName)
        {
            Process[] arrayProcess = Process.GetProcessesByName(processName);

            foreach (Process p in arrayProcess)
            {
                return p.Id;
            }
            return 0;
        }

        //根据进程名获取PID List
        public static List<int> GetPidListByProcessName(string processName)
        {
            List<int> listProcess = new List<int>();

            Process[] arrayProcess = Process.GetProcessesByName(processName);

            foreach (Process p in arrayProcess)
            {
                listProcess.Add(p.Id);
            }
            return listProcess;
        }

        //根据窗体标题查找窗口句柄（支持模糊匹配）
        public static IntPtr FindWindow(string title)
        {
            Process[] ps = Process.GetProcesses();
            foreach (Process p in ps)
            {
                if (p.MainWindowTitle.IndexOf(title) != -1)
                {
                    return p.MainWindowHandle;
                }
            }
            return IntPtr.Zero;
        }

        //根据窗体标题查找窗口句柄（支持模糊匹配）
        public static List<IntPtr> FindWindowListByTitle(string title)
        {
            List<IntPtr> listHandle = new List<IntPtr>();

            Process[] ps = Process.GetProcesses();

            foreach (Process p in ps)
            {
                if (p.MainWindowTitle.IndexOf(title) != -1)
                {
                    listHandle.Add(p.MainWindowHandle);
                }
            }
            return listHandle;
        }


        [DllImportAttribute("kernel32.dll", EntryPoint = "ReadProcessMemory")]
        public static extern bool ReadProcessMemory
        (
            IntPtr hProcess,
            IntPtr lpBaseAddress,
            IntPtr lpBuffer,
            int nSize,
            IntPtr lpNumberOfBytesRead
        );

        //写内存
        [DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")]
        public static extern bool WriteProcessMemory
        (
            IntPtr hProcess,
            IntPtr lpBaseAddress,
            int[] lpBuffer,
            int nSize,
            IntPtr lpNumberOfBytesWritten
        );

        //读取内存中的值
        public static int ReadMemoryValue(int processID, int baseAddress)
        {
            try
            {
                byte[] buffer = new byte[4];
                IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); //获取缓冲区地址
                IntPtr hProcess = OpenProcess(0x1F0FFF, false, processID);
                ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, 4, IntPtr.Zero); //将制定内存中的值读入缓冲区
                CloseHandle(hProcess);
                return Marshal.ReadInt32(byteAddress);
            }
            catch
            {
                return 0;
            }
        }

        public static int ReadMemoryValue(string processName, int baseAddress)
        {
            return ReadMemoryValue(GetPidByProcessName(processName), baseAddress);
        }

        //将值写入指定内存地址中
        public static bool WriteMemoryValue(int processID, int baseAddress, int value)
        {
            try
            {
                IntPtr hProcess = OpenProcess(0x1F0FFF, false, processID); //0x1F0FFF 最高权限
                bool bl = WriteProcessMemory(hProcess, (IntPtr)baseAddress, new int[] { value }, 4, IntPtr.Zero);
                CloseHandle(hProcess);
                return bl;
            }
            catch
            {
                return false;
            }
        }

        public static bool WriteMemoryValue(string processName, int baseAddress, int value)
        {
            return WriteMemoryValue(GetPidByProcessName(processName), baseAddress, value);
        }
    }
}

